﻿using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using static UnityEngine.SceneManagement.SceneManager;

[DefaultExecutionOrder(100)]
public class SceneController : Service
{
    private EventSystem eventSystem;
    private AudioPlayer audioPlayer;
    private SaveManager saveManager;

    private MyAudioSource bgm;
    public static int Index_Boot { get; private set; }
    public static int Index_Max { get; private set; }
    /// <summary>
    /// 是否异步加载场景
    /// </summary>
    public bool asynchronous;

    /// <summary>
    /// 开始异步加载场景时，发送异步操作
    /// </summary>
    public event UnityAction<AsyncOperation> AsyncLoadScene;

    [SerializeField]
    private int index;
    public int Index
    {
        get => index;
        private set
        {
            if (value > Index_Max)
                value = Index_Boot;
            if (value == index || value <= 0)
                return;
            index = value;
            if (value != Index_Max)
                bgm.Play(0f, true);
            else
                bgm.Stop();
            StartCoroutine(LoadSceneProcess(value, asynchronous));
        }
    }

    protected override void Awake()
    {
        base.Awake();
        eventSystem = Get<EventSystem>();
        audioPlayer = Get<AudioPlayer>();
        saveManager = Get<GameManager>().saveManager;
        Index_Max = SceneManager.sceneCountInBuildSettings - 1;
        Index_Boot = 5;
    }

    private void Start()
    {
        bgm = audioPlayer.CreateAudio("AudioSource/bgm_1", transform, false);
    }

    //禁止用不属于本类的方法加载场景
    public void LoadLevel(int index)
    {
        Index = index;
    }
    public void LoadNextLevel()
    {
        Index++;
    }
    public void RetuenToMenu()
    {
        Index = Index_Boot;
    }
    public void Quit()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
        Application.Quit();
#endif
    }

    /// <param name="confirm">加载到90%时是否需要确认</param>    
    private IEnumerator LoadSceneProcess(int index, bool async, bool confirm = false)
    {
        eventSystem.BeforeLoadScene?.Invoke(index);
        if (async)
        {
            AsyncOperation operation = LoadSceneAsync(index);
            AsyncLoadScene?.Invoke(operation);
            operation.allowSceneActivation = !confirm;
            operation.allowSceneActivation = false;
            yield return operation;
        }
        else
        {
            LoadScene(index);
        }
        yield return null;
        eventSystem.AfterSceneLoad?.Invoke(index);
    }

}
